<template>
  <!-- 数值区间控件 -->
  <div class="comp-remote-selector">
    <a-select
      mode="multiple"
      class="selector-item"
      size="small"
      :disabled="!inited || disabled || invalid"
      :value="value"
      :allow-clear="true"
      placeholder="全部"
      @search="handleSearch"
      @change="
        (value) => {
          onFieldChange(value)
        }
      "
    >
      <a-select-option v-for="(op, i) in options" :key="i" :value="op.value">{{
        op.label
      }}</a-select-option>
    </a-select>
  </div>
</template>
<script lang="ts">
import { loadGraphData, queryColumnInfo } from '@/api/widget'
import visGraphService from '@/store/modules/vis-graph-service'
import { GraphColumnEndWith } from '@/util/common'
import { message } from 'ant-design-vue'
import { cloneDeep, throttle } from 'lodash'
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'

const loadGraphDataThrottle = throttle(loadGraphData, 300)

export interface IRemoteSelector {
  tableName: string
  colName: string
  type: number
  dataId: number
  [key: string]: any
}

const nullValues = new Set([null, undefined])

/** 筛选表单 */
@Component({
  name: 'remote-selector',
})
export default class RemoteSelector extends Vue {
  /** 异步多选配置 */
  @Prop() config!: IRemoteSelector

  /** 禁用 */
  @Prop() disabled!: boolean

  /* 失效 */
  @Prop() invalid!: boolean

  /* 父组件实例 */
  @Prop() parent!: any

  /** 绑定值 */
  @Prop() value!: string[]

  /** 是否初始化 */
  inited: boolean = false

  /** 下拉选项 */
  options: any[] = []

  get projectId() {
    return (this.config as any).projectId
  }

  public onFieldChange(value: [number, number]) {
    this.$emit('input', value)
    this.$emit('change', value)
  }

  created() {
    this.search()
  }

  @Watch('config', { immediate: true, deep: true })
  getConfig() {
    this.search()
  }

  /** 响应下拉搜索 */
  handleSearch(value: string) {
    this.search(value)
  }

  getCacheData(key: string) {
    if (this.parent && this.parent.getColumnInfoByCache) {
      return this.parent.getColumnInfoByCache(key)
    }
    return null
  }

  /** 获取缓存字段 */
  getCacheKey(keywords: string) {
    return `${this.config.tableName}_${this.config.colName}_${this.config.type}_${this.config.dataId}_${keywords}`
  }

  async searchGraphData(keyWords: string = '') {
    let cacheData = await visGraphService.getCache(this.config.tableName)
    if (!cacheData) {
      const result: any = await loadGraphDataThrottle({
        data: {
          fileName: this.config.tableName,
          projectId: this.projectId,
        },
      })
      if (result?.data?.code === 100) {
        cacheData = result?.data?.result
        if (cacheData) {
          visGraphService.save({ id: this.config.tableName, data: cacheData })
        }
      }
    }
    const { nodes = [], links = [] } = (cacheData || {}) as any
    const dataList: any[] = this.config.colName.endsWith(
      GraphColumnEndWith.node
    )
      ? nodes
      : links
    this.findInData(dataList, keyWords)
  }

  private findInData(dataList: any[], keyWords: string = '') {
    let options = [] as any[]
    if (Array.isArray(dataList)) {
      const result = {} as any
      const colName = this.config.colName.split('[')[0]
      dataList.forEach((item) => {
        const find = (Array.isArray(item.attrs) ? item.attrs : []).find(
          (col: any) => col.key === colName
        )
        if (
          find &&
          !nullValues.has(find.value) &&
          (keyWords === '' ||
            /* eslint-disable */
            `${find.value}`.indexOf(keyWords) !== -1)
          /* eslint-enable */
        ) {
          result[find.value] = {
            label: find.value,
            value: find.value,
          }
        }
      })

      options = Object.values(result)
    }

    this.options = options
  }
  /** 初始化数据 */
  public search(keywords: string = '') {
    if (this.config.isGraphColumn) {
      this.searchGraphData(keywords)
      this.inited = true
      return
    }
    const cacheKey = this.getCacheKey(keywords)
    const cacheData = this.getCacheData(cacheKey)
    if (cacheData) {
      this.options = cacheData
      this.inited = true
      return
    }

    const dataSend = {
      data: {
        ...this.config,
        keywords: [null, undefined, ''].includes(keywords)
          ? undefined
          : keywords,
        pageSize: 20,
        curPage: 1,
      },
    }
    queryColumnInfo(dataSend).then((response) => {
      if (response.data.code === 100) {
        this.options = (response.data?.result?.pageCount?.data || []).map(
          (item: any) => {
            return {
              ...item,
              label: item.column,
              value: item.column,
            }
          }
        )
        if (this.parent && this.parent.setColumnInfo) {
          this.parent.setColumnInfo(cacheKey, cloneDeep(this.options))
        }
        this.inited = true
      } else {
        message.error('获取字段信息失败，请稍候重试')
      }
    })
  }
}
</script>
<style lang="less" scoped>
.comp-remote-selector {
  // height: 24px;
  width: 100%;

  /deep/ .ant-select-selection-selected-value {
    // font-size: 14px;
    line-height: 20px;
  }

  // /deep/ .ant-select-selection {
  //   height: 24px;
  // }

  /deep/ .ant-select-selection__rendered {
    // height: 25px;
    line-height: 16px;
  }

  /deep/ .ant-select-selection__choice {
    color: #373b52;
    font-size: 12px;
    // height: 22px;
    line-height: 20px;
  }

  /deep/ .ant-select-selection__placeholder {
    color: #373b52;
    font-size: 12px;
    line-height: 26px;
    margin-left: 0;
  }

  .row {
    align-items: center;
    display: flex;
    flex-flow: row nowrap;
  }

  .number-box {
    // height: 24px;
    width: calc(50% - 20px);

    /deep/ .ant-input-number-input-wrap {
      height: 24px;
    }

    /deep/ .ant-input-number-input {
      // height: 24px;
      line-height: 18px;
    }
  }

  .line {
    color: #5d637e;
    display: block;
    display: inline-block;
    height: 20%;
    padding: 0 10px;
    position: relative;
    text-align: center;
    width: 40px;
  }
}
</style>
